package api

import (
	"net/http"
	"time"

	"qmp_go_push/controllers"
	"qmp_go_push/middleware"
	"qmp_go_push/models"
	"qmp_go_push/pkg/logger"
	"qmp_go_push/pkg/request"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"go.uber.org/zap"
)

type GroupPath string

const (
	AdminApi GroupPath = "api/todo"
)

var groupMiddleware = map[GroupPath][]gin.HandlerFunc{
	AdminApi: []gin.HandlerFunc{middleware.CheckAdminApiAuth()},
}

type router struct {
	Path      string
	GroupPath GroupPath
	Method    string
	Callable  controllers.Callable
}

var routers = []router{}

func init() {
	routers = append(routers, adminApi...)
}

func RegisterRouters(engine *gin.Engine) {
	for _, item := range routers {
		group := engine.Group(string(item.GroupPath), groupMiddleware[item.GroupPath]...)
		group.Handle(item.Method, item.Path, func(context *gin.Context) {
			start := time.Now()
			// 全局日志链路ID
			traceId := uuid.New().String()
			context.Request.Header.Set("trace-id", traceId)

			teamUuid := context.GetString("team_uuid")
			userUuid := context.GetString("user_uuid")
			nickname := context.GetString("nickname")
			r := &request.Request{
				GinContext: context,
				DBContext:  models.NewDBContext(teamUuid, userUuid, nickname),
			}
			r.SetBody()

			response := item.Callable(r)
			response.TraceId = traceId

			context.JSON(http.StatusOK, response)

			go func() {
				logger.Info(logger.RequestLogger, "request-response",
					zap.String("trace_id", context.Request.Header.Get("trace-id")),
					zap.String("request_id", context.Request.Header.Get("request-id")),
					zap.String("path", context.Request.URL.Path),
					zap.String("method", context.Request.Method),
					zap.Any("param", r.GetBody()),
					zap.Any("response", response),
					zap.String("ip", context.ClientIP()),
					zap.String("ua", context.Request.UserAgent()),
					zap.Duration("timeout", time.Since(start)),
				)
			}()
		})
	}
}
